package cn.kent.base.threadLocal;

/**
 * ThreadLocal是jdk包提供的，提供了线程本地变量，如果你创建了一个ThreadLocal变量，那么访问这个变量的每个线程都有这个变量的一个本地副本。
 * 当多线程操作这个变量的时候，实际操作的是本地内存中的副本，从而避免了线程安全问题。
 * 创建一个ThreadLocal之后，每个线程都会复制一个变量到自己本地内存。
 *
 * ThreadLocal为什么设计成map结构？
 * 因为每个线程可以关联多个ThreadLocal变量
 *
 * ThreadLocal可能导致的问题？
 * 可能会内存溢出，因为如果使用了内存变量但是不清除，可能会导致内存溢出。
 * 原理：因为key是定义的ThreadLocal的this引用，value为我们set方法塞的值。
 * 如果线程一直消亡，那么这些变量会一直存在，可能会导致内存溢出。
 *
 * ThreadLocalRandom就是借鉴ThreadLocal思想实现的。
 */
public class ThreadLocalTest {
    static void print(String str) {
        // 打印本地内存中的localVariable变量副本值
        System.out.println(str + " : " + localVariable.get());
        // 清除本地副本
        // localVariable.remove();
    }

    static ThreadLocal<String> localVariable = new ThreadLocal<>();

    public static void main(String[] args) {
        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                localVariable.set("threadA local variable"); // 实际设置的是线程A本地内存中的副本，线程B是无法访问的
                print("threadA");
                // 打印本地变量值
                System.out.println("threadA remove after" + " : " + localVariable.get());
            }
        });

        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                localVariable.set("threadB local variable");
                print("threadB");
                // 打印本地变量值
                System.out.println("threadB remove after" + " : " + localVariable.get());
            }
        });

        threadA.start();
        threadB.start();

    }
}
